Next | Prev | Up | Top | Contents | Index
Waiting for Time to Pass
The kernel offers functions for timed delays, as summarized in Table 9-21.
Functions for Timed Delays
Function Name | Header Files | Can Sleep? | Purpose |
---|
delay(D3) | ddi.h | Y | Delay for a specified number of clock ticks. |
drv_hztousec(D3) | ddi.h | N | Convert clock ticks to microseconds |
drv_usectohz(D3) | ddi.h | N | Convert microseconds to clock ticks. |
drv_usecwait(D3) | ddi.h | N | Busy-wait for a specified interval. |
dtimeout(D3) | ddi.h & ksynch.h | N | Schedule a function execute on a specified processor after a specified length of time. |
itimeout(D3) | ddi.h & ksynch.h | N | Schedule a function to be executed after a specified number of clock ticks. |
fast_itimeout(D3) | ddi.h & ksynch.h | N | Same as itimeout() but takes an interval in "fast ticks." |
fasthzto(D3) | types.h & time.h | N | Returns the value of a struct timeval as a count of "fast ticks." |
timeout(D3) | ddi.h & ksynch.h | N | Schedule a function to be executed after a specified number of clock ticks. |
untimeout(D3) | ddi.h | N | Cancel a previous itimeout or fast_itimeout request. |
untimeout_func(D3) | ddi.h | N | Cancel a previous itimeout or fast_itimeout request by function name. |
Time Units
The basic time unit is the "tick." Its value can differ between hardware platforms and between versions of IRIX. The drvhztousec() and drvusectohz() functions convert between ticks and microseconds in the current system. Use them in order to schedule a delay in a portable mannter. (However, the timer function precision is the tick, not the microsecond.)
The "fast tick" is a fraction of a tick. Like the tick, the fast tick's value can differ between systems. Use fasthzto() to convert from microseconds to fast ticks.
Timer Support
Timer support is based on the idea of a "callback" function. You specify the following to dtimeout(), itimeout(), timeout() or fast_itimeout():
- an interval in clock ticks or fast ticks
- a function to be called at the expiration of the interval
- one or more arguments to be passed to the function
- a priority (interrupt) level at which the function should run
After a delay of at least the length requested, the function is called. The function is entered asynchronously. On a uniprocessor, it can interrupt execution of an upper-half routine. On a multiprocessor, it can execute concurrently with an upper-half routine or with an interrupt handler. You should not rely on the priority level of the function for mutual exclusion (see "Priority Level Functions" for an explanation).
The difference between itimeout() and timeout() is that the latter takes no argument values to be passed to the function when it is called. In order to get a repeated series of timer events, start a new timeout from the callback function.
The untimeout() and untimeout_func() functions cancel a pending timeout. In a loadable driver that has an pfxunload() entry point, cancel any pending timeouts before unloading.
The STREAMS_TIMOUT macro supplies similar timeout capability for a STREAMS driver (see "Special Considerations for Multiprocessing").
Short-Term Delay Support
In rare circumstances, a driver needs to pause briefly between two hardware operations. For example, the Silicon Graphics support for external interrupts in the Challenge and Onyx computers sometimes needs to set a high output level, wait for a brief, precise interval, then set a low output level.
The drv_usecwait() function supports this type of very short, precisely-timed delay. It "spins" for a specified number of microseconds, then returns to the caller. The CPU does nothing else during this period, so clearly a delay of more than a few microseconds can interfere with other work. Furthermore, if interrupts are disabled during the wait, the response to another interrupt is delayed also--the delay contributes directly to the "latency" of interrupt handling.
Next | Prev | Up | Top | Contents | Index